package com.jiangjiang.eshop.membership.updater;

import com.jiangjiang.eshop.membership.domain.MemberLevelDetailEntity;
import com.jiangjiang.eshop.membership.domain.MemberLevelEntity;
import com.jiangjiang.eshop.membership.domain.MemberPointDetailEntity;
import com.jiangjiang.eshop.membership.service.MemberLevelDetailService;
import com.jiangjiang.eshop.membership.service.MemberLevelService;
import com.jiangjiang.eshop.membership.service.MemberPointDetailService;
import com.jiangjiang.eshop.membership.service.MemberPointService;
import org.apache.ibatis.annotations.Update;

import java.util.Map;
import java.util.Objects;

/**
 * @ClassName AbstractMembershipUpdater
 * @Description TODO
 * @Author jhw
 * @Date 2021/9/4 17:34
 * @Version 1.0
 **/
public abstract class AbstractMembershipUpdater<T, K> implements MembershipUpdater<T, K> {

    /**
     * 会员等级明细管理service
     */
    protected MemberLevelDetailService memberLevelDetailService;

    /**
     * 会员积分明细管理Service
     */
    protected MemberPointDetailService memberPointDetailService;

    public AbstractMembershipUpdater(MemberLevelDetailService memberLevelDetailService,
                                     MemberPointDetailService memberPointDetailService) {
        this.memberLevelDetailService = memberLevelDetailService;
        this.memberPointDetailService = memberPointDetailService;
    }

    /**
     * 执行会员信息更新操作
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @return
     * @throws Exception
     */
    @Override
    public K execute(Long userAccountId, T parameter) throws Exception {
        // 更新会员等级
        MemberLevelDetailEntity updateMemberLevelDetail = updateMemberLevel(userAccountId, parameter);
        // 更新会员积分
        MemberPointDetailEntity updateMemberPointDetail = updateMemberPoint(userAccountId, parameter);
        // 保存会员等级明细
        saveMemberLevelDetail(userAccountId, parameter, updateMemberLevelDetail);
        // 保存会员积分明细
        saveMemberPointDetail(userAccountId, parameter, updateMemberPointDetail);
        // 获取执行结果
        return getExecuteResult(userAccountId, parameter);
    }

    /**
     * 会员等级更新
     *
     * @param userAccountId 用户账户id
     * @param parameter     参数
     * @return 返回值
     */
    protected abstract MemberLevelDetailEntity updateMemberLevel(Long userAccountId, T parameter) throws Exception;

    /**
     * 更新会员积分
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @return 更新结果
     * @throws Exception
     */
    protected abstract MemberPointDetailEntity updateMemberPoint(Long userAccountId, T parameter) throws Exception;

    /**
     * 新增一条会员等级更新明细
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @param detailEntity  更新会员等级结果
     * @throws Exception
     */
    private void saveMemberLevelDetail(Long userAccountId,
                                       T parameter,
                                       MemberLevelDetailEntity detailEntity) throws Exception {
        if(Objects.isNull(detailEntity)) {return;}
        detailEntity.setUserAccountId(userAccountId);
        detailEntity.setUpdateReason(getMemberLevelUpdateReason(userAccountId, parameter));
        memberLevelDetailService.save(detailEntity);
    }

    /**
     * 新增一条会员积分更新明细
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @param detailEntity  更新会员积分结果
     * @throws Exception
     */
    private void saveMemberPointDetail(Long userAccountId,
                                       T parameter,
                                       MemberPointDetailEntity detailEntity) {
        if(Objects.isNull(detailEntity)) {return;}
        detailEntity.setUserAccountId(userAccountId);
        detailEntity.setUpdateReason(getMemberPointUpdateReason(userAccountId, parameter));
        memberPointDetailService.save(detailEntity);

    }

    /**
     * 获取最终执行结果
     *
     * @param userAccountId
     * @param parameter
     * @return
     */
    protected abstract K getExecuteResult(Long userAccountId, T parameter) throws Exception;

    /**
     * 获取用户等级更新原因
     *
     * @param userAccountId
     * @param parameter
     * @return
     */
    protected abstract String getMemberLevelUpdateReason(Long userAccountId, T parameter);

    /**
     * 获取用户积分更新原因
     *
     * @param userAccountId
     * @param parameter
     * @return
     */
    protected abstract String getMemberPointUpdateReason(Long userAccountId, T parameter);



    /**
     * 撤销会员信息更新操作
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @return
     * @throws Exception
     */
    @Override
    public K undo(Long userAccountId, T parameter) throws Exception {
        // 撤销更新会员等级
        MemberLevelDetailEntity undoUpdateMemberLevelDetail = undoUpdateMemberLevel(userAccountId, parameter);
        // 撤销更新会员积分
        MemberPointDetailEntity undoUpdateMemberPointDetail = undoUpdateMemberPoint(userAccountId, parameter);
        // 撤销保存会员等级明细
        saveUndoMemberLevelDetail(userAccountId, parameter, undoUpdateMemberLevelDetail);
        // 撤销保存会员积分明细
        saveUndoMemberPointDetail(userAccountId, parameter, undoUpdateMemberPointDetail);
        // 获取撤销结果
        return getUndoResult(userAccountId, parameter);
    }


    /**
     * 会员等级更新
     *
     * @param userAccountId 用户账户id
     * @param parameter     参数
     * @return 返回值
     */
    protected abstract MemberLevelDetailEntity undoUpdateMemberLevel(Long userAccountId, T parameter) throws Exception;

    /**
     * 更新会员积分
     *
     * @param userAccountId 用户账号id
     * @param parameter     参数
     * @return 更新结果
     * @throws Exception
     */
    protected abstract MemberPointDetailEntity undoUpdateMemberPoint(Long userAccountId, T parameter) throws Exception;

    /**
     * 新增一条会员等级更新撤销明细
     *
     * @param userAccountId           用户账号id
     * @param parameter               参数
     * @param memberLevelDetailEntity 会员等级更新明细数据
     * @throws Exception
     */
    private void saveUndoMemberLevelDetail(Long userAccountId,
                                           T parameter,
                                           MemberLevelDetailEntity memberLevelDetailEntity) throws Exception {

        if(Objects.isNull(memberLevelDetailEntity)){
            return;
        }
        memberLevelDetailEntity.setUserAccountId(userAccountId);
        memberLevelDetailEntity.setUpdateReason(getUndoMemberLevelUpdateReason(userAccountId, parameter));
        memberLevelDetailService.save(memberLevelDetailEntity);
    }



    /**
     * 新增一条会员积分更新明细
     *
     * @param userAccountId           用户账号id
     * @param parameter               参数
     * @param memberPointDetailEntity 更新会员积分结果
     * @throws Exception
     */
    private void saveUndoMemberPointDetail(Long userAccountId,
                                           T parameter,
                                           MemberPointDetailEntity memberPointDetailEntity) throws Exception {
        if(Objects.isNull(memberPointDetailEntity)) {return;}
        memberPointDetailEntity.setUserAccountId(userAccountId);
        memberPointDetailEntity.setUpdateReason(getUndoMemberPointUpdateReason(userAccountId, parameter));
        memberPointDetailService.save(memberPointDetailEntity);
    }


    /**
     * 获取最终执行结果
     *
     * @param userAccountId
     * @param parameter
     * @return
     */
    protected abstract K getUndoResult(Long userAccountId, T parameter) throws Exception;

    /**
     * 获取会员等级更新撤销原因
     * @param userAccountId 用户账户
     * @param parameter 请求参数
     * @return 查询结果
     */
    protected abstract String getUndoMemberLevelUpdateReason(Long userAccountId, Object parameter);

    /**
     * 获取会员积分更新撤销原因
     * @param userAccountId 用户账户
     * @param parameter 请求参数
     * @return 查询结果
     */
    protected abstract String getUndoMemberPointUpdateReason(Long userAccountId, Object parameter);
}
